'use client';

import { useEffect, useRef, useState } from 'react';
import { FamilyMember } from '../types/family';
import { convertToAncientNumber, convertDateToAncient } from '../types/ancientNumberMap';
import { generatePDF } from '../utils/pdfGenerator';
import * as d3 from 'd3';

interface TreeViewD3Props {
  familyData: FamilyMember[];
}

interface TreeNode extends d3.HierarchyNode<FamilyMember> {
  x?: number;
  y?: number;
}

export default function TreeViewD3({ familyData }: TreeViewD3Props) {
  const svgRef = useRef<SVGSVGElement>(null);
  const containerRef = useRef<HTMLDivElement>(null);
  const [selectedNode, setSelectedNode] = useState<FamilyMember | null>(null);
  const [isMaximized, setIsMaximized] = useState(false);
  const [isPanelCollapsed, setIsPanelCollapsed] = useState(false);

  const formatDateRange = (birthDate: string, deathDate: string) => {
    const birth = birthDate ? convertDateToAncient(birthDate) : '?';
    const death = deathDate ? convertDateToAncient(deathDate) : '在世';
    return `${birth} - ${death}`;
  };

  const toggleMaximize = () => {
    setIsMaximized(!isMaximized);
  };

  // 监听ESC键退出最大化
  useEffect(() => {
    const handleKeyDown = (event: KeyboardEvent) => {
      if (event.key === 'Escape' && isMaximized) {
        setIsMaximized(false);
      }
    };

    if (isMaximized) {
      document.addEventListener('keydown', handleKeyDown);
      // 防止页面滚动
      document.body.style.overflow = 'hidden';
    } else {
      document.body.style.overflow = 'auto';
    }

    return () => {
      document.removeEventListener('keydown', handleKeyDown);
      document.body.style.overflow = 'auto';
    };
  }, [isMaximized]);

  const downloadPDF = async () => {
    try {
      await generatePDF('d3-content', {
        filename: '族谱关系图-D3.pdf',
        orientation: 'landscape',
        format: 'a3'
      });
    } catch (error) {
      alert('PDF生成失败，请重试');
    }
  };

  // 构建层次数据结构
  const buildHierarchy = (data: FamilyMember[]): FamilyMember | null => {
    if (!data.length) return null;

    // 找到根节点（没有父节点的节点）
    const roots = data.filter(person => !person.parentId);
    if (roots.length === 0) return data[0]; // 如果没有根节点，取第一个

    const root = roots[0];

    // 递归构建子节点
    const buildChildren = (parent: FamilyMember): FamilyMember => {
      const children = data.filter(person => person.parentId === parent.id);
      return {
        ...parent,
        children: children.length > 0 ? children.map(buildChildren) : undefined
      } as FamilyMember & { children?: FamilyMember[] };
    };

    return buildChildren(root);
  };

  useEffect(() => {
    if (!familyData.length || !svgRef.current || !containerRef.current) return;

    const svg = d3.select(svgRef.current);
    svg.selectAll("*").remove(); // 清除之前的内容

    const container = containerRef.current;
    const width = container.clientWidth;
    const height = container.clientHeight;

    // 构建层次数据
    const hierarchyData = buildHierarchy(familyData);
    if (!hierarchyData) return;

    // 创建层次结构
    const root = d3.hierarchy(hierarchyData);

    // 根据最大化状态和窗口大小优化布局参数
    const nodeWidth = 120;
    const nodeHeight = 60;

    // 根据是否最大化调整间距和尺寸
    let minHorizontalSpacing, verticalSpacing, layoutPadding;

    if (isMaximized) {
      // 最大化时：利用全屏空间，优化大型族谱展示
      const screenWidth = window.innerWidth;
      const screenHeight = window.innerHeight;

      // 根据屏幕尺寸动态调整间距
      minHorizontalSpacing = Math.max(150, Math.min(250, screenWidth / 8)); // 150-250px
      verticalSpacing = Math.max(120, Math.min(200, screenHeight / 6)); // 120-200px
      layoutPadding = 100;

      // 更新容器尺寸为全屏
      container.style.width = `${screenWidth}px`;
      container.style.height = `${screenHeight - 120}px`; // 减去工具栏高度
    } else {
      // 普通模式：保持原有间距
      minHorizontalSpacing = 180;
      verticalSpacing = 150;
      layoutPadding = 200;
    }

    // 计算每层的节点数量
    const levelCounts: number[] = [];
    root.descendants().forEach(d => {
      const level = d.depth;
      levelCounts[level] = (levelCounts[level] || 0) + 1;
    });

    // 计算所需的最小宽度
    const maxNodesInLevel = Math.max(...levelCounts);
    const requiredWidth = Math.max(width - layoutPadding, maxNodesInLevel * minHorizontalSpacing);
    const requiredHeight = Math.max(height - layoutPadding, levelCounts.length * verticalSpacing);

    // 创建树布局 - 根据最大化状态优化尺寸和间距
    const treeLayout = d3.tree<FamilyMember>()
      .size([requiredWidth, requiredHeight])
      .separation((a, b) => {
        // 根据最大化状态动态调整间距
        const baseSpacing = minHorizontalSpacing / nodeWidth;
        const spacingMultiplier = isMaximized ? 1.2 : 1.5; // 最大化时稍微紧凑一些

        if (a.parent === b.parent) {
          return baseSpacing * spacingMultiplier; // 同级节点间距
        } else {
          return baseSpacing * (spacingMultiplier + 0.5); // 不同分支间距
        }
      });

    // 应用布局
    treeLayout(root);

    // 调整节点位置，确保有足够的垂直间距
    root.descendants().forEach(d => {
      d.y = d.depth * verticalSpacing; // 增加层级间距，避免重叠
    });

    // 添加箭头标记定义
    const defs = svg.append("defs");

    defs.append("marker")
      .attr("id", "arrowhead")
      .attr("viewBox", "0 -5 10 10")
      .attr("refX", 8)
      .attr("refY", 0)
      .attr("markerWidth", 6)
      .attr("markerHeight", 6)
      .attr("orient", "auto")
      .append("path")
      .attr("d", "M0,-5L10,0L0,5")
      .attr("fill", "#6b7280");

    // 创建主要的g元素
    const g = svg.append("g")
      .attr("transform", "translate(100, 100)");

    // 添加缩放和拖拽行为
    const zoom = d3.zoom<SVGSVGElement, unknown>()
      .scaleExtent([0.1, 3])
      .on("zoom", (event) => {
        g.attr("transform", event.transform);
      });

    svg.call(zoom);

    // 绘制连线 - 添加箭头
    const links = g.selectAll(".link")
      .data(root.links())
      .enter()
      .append("path")
      .attr("class", "link")
      .attr("d", (d) => {
        // 自定义路径，确保箭头指向子节点的顶部
        const source = d.source;
        const target = d.target;

        // 计算连线路径，从父节点底部到子节点顶部
        const sourceX = source.x!;
        const sourceY = source.y! + 30; // 父节点底部
        const targetX = target.x!;
        const targetY = target.y! - 30; // 子节点顶部

        // 创建贝塞尔曲线路径
        const midY = (sourceY + targetY) / 2;

        return `M${sourceX},${sourceY}C${sourceX},${midY} ${targetX},${midY} ${targetX},${targetY}`;
      })
      .attr("fill", "none")
      .attr("stroke", "#6b7280")
      .attr("stroke-width", 2)
      .attr("marker-end", "url(#arrowhead)"); // 添加箭头

    // 绘制节点
    const nodes = g.selectAll(".node")
      .data(root.descendants())
      .enter()
      .append("g")
      .attr("class", "node")
      .attr("transform", d => `translate(${d.x}, ${d.y})`)
      .style("cursor", "pointer")
      .on("click", (event, d) => {
        event.stopPropagation();
        setSelectedNode(d.data);

        // 高亮选中的节点
        nodes.selectAll("rect").attr("stroke-width", 2);
        d3.select(event.currentTarget).select("rect").attr("stroke-width", 4);
      });

    // 添加节点矩形
    nodes.append("rect")
      .attr("x", -60)
      .attr("y", -30)
      .attr("width", 120)
      .attr("height", 60)
      .attr("rx", 8)
      .attr("fill", d => {
        const isMale = (d.data.gender || 'male') === 'male';
        return isMale ? '#dbeafe' : '#fce7f3';
      })
      .attr("stroke", d => {
        const isMale = (d.data.gender || 'male') === 'male';
        return isMale ? '#3b82f6' : '#ec4899';
      })
      .attr("stroke-width", 2)
      .on("mouseover", function () {
        d3.select(this).attr("opacity", 0.8);
      })
      .on("mouseout", function () {
        d3.select(this).attr("opacity", 1);
      });

    // 添加节点文本 - 姓名
    nodes.append("text")
      .attr("dy", "-5")
      .attr("text-anchor", "middle")
      .style("font-size", "14px")
      .style("font-weight", "bold")
      .style("fill", d => {
        const isMale = (d.data.gender || 'male') === 'male';
        return isMale ? '#1e40af' : '#be185d';
      })
      .text(d => d.data.name);

    // 添加节点文本 - 世次
    nodes.append("text")
      .attr("dy", "15")
      .attr("text-anchor", "middle")
      .style("font-size", "12px")
      .style("fill", d => {
        const isMale = (d.data.gender || 'male') === 'male';
        return isMale ? '#1e40af' : '#be185d';
      })
      .text(d => `第${convertToAncientNumber(d.data.generation)}世`);

    // 添加工具栏功能
    const toolbar = d3.select(container)
      .select(".d3-toolbar");

    // 重置视图函数 - 根据最大化状态优化显示
    const resetView = () => {
      // 计算所有节点的边界
      const nodes = root.descendants();
      if (nodes.length === 0) return;

      const bounds = {
        minX: Math.min(...nodes.map(d => d.x! - nodeWidth / 2)),
        maxX: Math.max(...nodes.map(d => d.x! + nodeWidth / 2)),
        minY: Math.min(...nodes.map(d => d.y! - nodeHeight / 2)),
        maxY: Math.max(...nodes.map(d => d.y! + nodeHeight / 2))
      };

      const graphWidth = bounds.maxX - bounds.minX + 100;
      const graphHeight = bounds.maxY - bounds.minY + 100;

      // 获取当前容器尺寸
      const containerWidth = container.clientWidth;
      const containerHeight = container.clientHeight;

      // 根据最大化状态调整缩放策略
      let scaleX, scaleY, scale;

      if (isMaximized) {
        // 最大化时：优先保证内容完整可见，允许较小的缩放
        scaleX = (containerWidth - 50) / graphWidth;
        scaleY = (containerHeight - 50) / graphHeight;
        scale = Math.min(scaleX, scaleY, 1.2); // 允许稍微放大

        // 如果内容太大，确保至少能看到主要结构
        if (scale < 0.3) {
          scale = Math.max(0.3, Math.min(scaleX, scaleY));
        }
      } else {
        // 普通模式：保持原有逻辑
        scaleX = containerWidth / graphWidth;
        scaleY = containerHeight / graphHeight;
        scale = Math.min(scaleX, scaleY, 1);
      }

      // 计算居中位置
      const centerX = containerWidth / 2 - (bounds.minX + bounds.maxX) / 2 * scale;
      const centerY = containerHeight / 2 - (bounds.minY + bounds.maxY) / 2 * scale;

      svg.transition()
        .duration(750)
        .call(zoom.transform, d3.zoomIdentity.translate(centerX, centerY).scale(scale));
    };

    // 放大函数
    const zoomIn = () => {
      svg.transition()
        .duration(300)
        .call(zoom.scaleBy, 1.2);
    };

    // 缩小函数
    const zoomOut = () => {
      svg.transition()
        .duration(300)
        .call(zoom.scaleBy, 1 / 1.2);
    };

    // 绑定工具栏事件（通过全局函数）
    (window as any).d3TreeZoomIn = zoomIn;
    (window as any).d3TreeZoomOut = zoomOut;
    (window as any).d3TreeReset = resetView;

    // 初始化时自动适应视图
    setTimeout(() => {
      resetView();
    }, 100);

    // 在最大化状态下监听窗口大小变化
    const handleResize = () => {
      if (isMaximized) {
        // 延迟执行，避免频繁重绘
        setTimeout(() => {
          resetView();
        }, 200);
      }
    };

    if (isMaximized) {
      window.addEventListener('resize', handleResize);
    }

    // 清理函数
    return () => {
      delete (window as any).d3TreeZoomIn;
      delete (window as any).d3TreeZoomOut;
      delete (window as any).d3TreeReset;

      if (isMaximized) {
        window.removeEventListener('resize', handleResize);
      }
    };

  }, [familyData, isPanelCollapsed, isMaximized]);

  if (familyData.length === 0) {
    return (
      <div className="flex items-center justify-center h-64">
        <p className="text-gray-500 text-lg">暂无族谱数据，请先添加成员</p>
      </div>
    );
  }

  return (
    <div className={`${isMaximized ? 'fixed inset-0 z-50 bg-white' : 'p-6 h-screen'} flex flex-col`}>
      <div className={`flex justify-between items-center mb-4 ${isMaximized ? 'px-6 py-4 border-b bg-gray-50' : ''}`}>
        <h2 className={`${isMaximized ? 'text-3xl' : 'text-2xl'} font-bold text-gray-800`}>
          家族关系图 - D3树形布局 {isMaximized ? '(全屏模式)' : ''}
        </h2>
        <div className="flex gap-2 d3-toolbar">
          <button
            onClick={() => (window as any).d3TreeZoomIn?.()}
            className="px-3 py-1 text-sm bg-blue-500 text-white rounded hover:bg-blue-600 transition-colors flex items-center gap-1"
            title="放大族谱图"
          >
            <svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
              <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 6v6m0 0v6m0-6h6m-6 0H6" />
            </svg>
            放大
          </button>
          <button
            onClick={() => (window as any).d3TreeZoomOut?.()}
            className="px-3 py-1 text-sm bg-blue-500 text-white rounded hover:bg-blue-600 transition-colors flex items-center gap-1"
            title="缩小族谱图"
          >
            <svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
              <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M18 12H6" />
            </svg>
            缩小
          </button>
          <button
            onClick={() => (window as any).d3TreeReset?.()}
            className="px-3 py-1 text-sm bg-blue-500 text-white rounded hover:bg-blue-600 transition-colors flex items-center gap-1"
            title="重置视图"
          >
            <svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
              <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15" />
            </svg>
            重置
          </button>
          <button
            onClick={toggleMaximize}
            className="px-3 py-1 text-sm bg-purple-500 text-white rounded hover:bg-purple-600 transition-colors flex items-center gap-1"
            title={isMaximized ? '还原窗口' : '最大化'}
          >
            {isMaximized ? (
              <>
                <svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                  <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M4 8V4m0 0h4M4 4l5 5m11-1V4m0 0h-4m4 0l-5 5M4 16v4m0 0h4m-4 0l5-5m11 5l-5-5m5 5v-4m0 4h-4" />
                </svg>
                还原
              </>
            ) : (
              <>
                <svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                  <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M4 8l4-4m0 0h4m-4 0v4m12-4l-4 4m0 0v4m0-4h4m-8 8l-4-4m0 0v-4m0 4h-4m8 0l4 4m0 0v-4m0 4h-4" />
                </svg>
                最大化
              </>
            )}
          </button>
          <button
            onClick={downloadPDF}
            className="px-3 py-1 text-sm bg-green-500 text-white rounded hover:bg-green-600 transition-colors flex items-center gap-1"
            title="下载PDF"
          >
            <svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
              <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 10v6m0 0l-3-3m3 3l3-3m2 8H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z" />
            </svg>
            下载PDF
          </button>
          {selectedNode && (
            <button
              onClick={() => setIsPanelCollapsed(!isPanelCollapsed)}
              className="px-3 py-1 text-sm bg-gray-500 text-white rounded hover:bg-gray-600 transition-colors flex items-center gap-1"
              title={isPanelCollapsed ? '展开信息面板' : '收起信息面板'}
            >
              {isPanelCollapsed ? (
                <>
                  <svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                    <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 5l7 7-7 7" />
                  </svg>
                  展开面板
                </>
              ) : (
                <>
                  <svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                    <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M15 19l-7-7 7-7" />
                  </svg>
                  收起面板
                </>
              )}
            </button>
          )}
        </div>
      </div>

      <div className={`flex flex-1 gap-4 ${isMaximized ? 'px-6' : ''}`}>
        {/* 图形区域 */}
        <div className={`flex-1 ${isMaximized ? 'border-0' : 'border border-gray-300 rounded-lg'} overflow-hidden bg-white`}>
          <div
            id="d3-content"
            ref={containerRef}
            className="w-full h-full relative"
          >
            <svg
              ref={svgRef}
              className="w-full h-full"
              style={{
                cursor: 'grab',
                minWidth: '100%',
                minHeight: '100%'
              }}
              preserveAspectRatio="xMidYMid meet"
            />
          </div>
        </div>

        {/* 详细信息面板 */}
        {selectedNode && (
          <div className={`${isPanelCollapsed ? 'w-12' : 'w-80'} bg-white border border-gray-300 rounded-lg overflow-hidden transition-all duration-300`}>
            {/* 面板头部 */}
            <div className="flex items-center justify-between p-3 bg-gray-50 border-b">
              {!isPanelCollapsed && (
                <h3 className="text-lg font-bold">
                  <span className={`${(selectedNode.gender || 'male') === 'male' ? 'text-blue-600' : 'text-pink-600'}`}>
                    {selectedNode.name}
                  </span>
                </h3>
              )}
              <button
                onClick={() => setIsPanelCollapsed(!isPanelCollapsed)}
                className="p-1 hover:bg-gray-200 rounded transition-colors"
                title={isPanelCollapsed ? '展开详细信息' : '收起详细信息'}
              >
                <svg
                  className={`w-4 h-4 transition-transform duration-200 ${isPanelCollapsed ? 'rotate-180' : ''}`}
                  fill="none"
                  stroke="currentColor"
                  viewBox="0 0 24 24"
                >
                  <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M15 19l-7-7 7-7" />
                </svg>
              </button>
            </div>

            {/* 面板内容 */}
            {!isPanelCollapsed && (
              <div className="p-4 overflow-y-auto max-h-full">
                <div className="space-y-3 text-sm">
                  <div>
                    <strong>性别:</strong> {(selectedNode.gender || 'male') === 'male' ? '男' : '女'}
                  </div>
                  <div>
                    <strong>世次:</strong> 第{convertToAncientNumber(selectedNode.generation)}世
                  </div>
                  <div>
                    <strong>何人子女:</strong> {
                      selectedNode.parentId
                        ? familyData.find(p => p.id === selectedNode.parentId)?.name || '无'
                        : '始祖'
                    }
                  </div>
                  <div>
                    <strong>排行:</strong> {selectedNode.ranking || '无'}
                  </div>
                  <div>
                    <strong>生终年月:</strong> {formatDateRange(selectedNode.birthDate, selectedNode.deathDate)}
                  </div>
                  {selectedNode.biography && (
                    <div>
                      <strong>履历:</strong> {selectedNode.biography}
                    </div>
                  )}
                  <div>
                    <strong>配偶:</strong>
                    <span className={selectedNode.spouseName ? ((selectedNode.gender || 'male') === 'male' ? 'text-pink-600' : 'text-blue-600') : ''}>
                      {selectedNode.spouseName || '无'}
                    </span>
                  </div>
                  {selectedNode.spouseName && (
                    <div>
                      <strong>配偶生终年月:</strong> {formatDateRange(selectedNode.spouseBirthDate, selectedNode.spouseDeathDate)}
                    </div>
                  )}
                  {selectedNode.spouseBiography && (
                    <div>
                      <strong>配偶履历:</strong> {selectedNode.spouseBiography}
                    </div>
                  )}
                  <div>
                    <strong>现在住址:</strong> {selectedNode.town + selectedNode.county}
                  </div>
                  {selectedNode.notes && (
                    <div>
                      <strong>备注:</strong> {selectedNode.notes}
                    </div>
                  )}
                  <div>
                    <strong>子女数量:</strong> {
                      familyData.filter(p => p.parentId === selectedNode.id).length
                    }人
                  </div>

                  {/* 关闭按钮 */}
                  <div className="pt-3 border-t">
                    <button
                      onClick={() => setSelectedNode(null)}
                      className="w-full px-3 py-2 text-sm bg-gray-100 text-gray-700 rounded hover:bg-gray-200 transition-colors"
                    >
                      关闭详细信息
                    </button>
                  </div>
                </div>
              </div>
            )}

            {/* 收起状态下的提示 */}
            {isPanelCollapsed && (
              <div className="p-2 text-center">
                <div className="text-xs text-gray-500 transform rotate-90 whitespace-nowrap">
                  详细信息
                </div>
              </div>
            )}
          </div>
        )}
      </div>

      {!isMaximized && (
        <div className="mt-4 text-sm text-gray-600 text-center">
          D3树形布局 | 点击节点查看详细信息 | 支持缩放和拖拽 | 鼠标滚轮缩放 | 按ESC退出全屏
        </div>
      )}

      {isMaximized && (
        <div className="fixed bottom-4 left-1/2 transform -translate-x-1/2 bg-black bg-opacity-75 text-white px-4 py-2 rounded-lg text-sm">
          全屏模式 | 已优化大屏显示 | 按ESC或点击还原按钮退出 | 节点间距: {Math.round((window.innerWidth || 1200) / 8)}px
        </div>
      )}
    </div>
  );
}